package fr.gdi.android.news.api.oauth;

import junit.framework.Assert;
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import oauth.signpost.signature.HmacSha1MessageSigner;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;


public abstract class AbstractOAuthActivity extends Activity
{
    
    public static final String USER_TOKEN = "user_token";
    public static final String USER_SECRET = "user_secret";
    
    private OAuthConsumer mConsumer = null;
    private OAuthProvider mProvider = null;
    
    SharedPreferences mSettings;
    
    public void onCreate(Bundle icicle)
    {
        super.onCreate(icicle);
        
        mConsumer = new CommonsHttpOAuthConsumer(getConsumerKey(), getConsumerSecret());
        mConsumer.setMessageSigner(new HmacSha1MessageSigner());
        
        mProvider = new CommonsHttpOAuthProvider(getRequestTokenUrl(), getAccessTokenUrl(), getAuthorizeUrl());
        mProvider.setOAuth10a(true);
        
        mSettings = PreferenceManager.getDefaultSharedPreferences(this);
        
        Intent i = this.getIntent();
        if (i.getData() == null)
        {
            try
            {
                String authUrl = mProvider.retrieveRequestToken(mConsumer, getCallbackUri().toString());
                saveRequestInformation(mConsumer.getToken(), mConsumer.getTokenSecret());
                Intent intent = new Intent(this, getBrowsingActivityClass());
                intent.setData(Uri.parse(authUrl));
                //Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl));
                intent.putExtra("url", authUrl);
                this.startActivity(intent);
            }
            catch (Exception e)
            {
                Log.e(getPackageName(), "Unable to authenticate", e);
            }
        }
    }
    
    protected abstract String getConsumerKey();
    protected abstract String getConsumerSecret();
    
    protected abstract String getRequestToken();
    protected abstract String getRequestSecret();
    
    protected abstract String getRequestTokenUrl();
    protected abstract String getAccessTokenUrl();
    protected abstract String getAuthorizeUrl();
    protected abstract String getVerifyUrl();
    
    protected abstract Uri getCallbackUri();
    
    protected abstract Class<? extends Activity> getBrowsingActivityClass();
    protected abstract Class<? extends Activity> getOnSuccessfulAuthenticationActivityClass();
    
    @Override
    protected void onResume()
    {
        super.onResume();
        
        Uri uri = getIntent().getData();
        if (uri != null && getCallbackUri().getScheme().equals(uri.getScheme()))
        {
            String token = mSettings.getString(getRequestToken(), null);
            String secret = mSettings.getString(getRequestSecret(), null);
            
            Intent i = new Intent(this, getOnSuccessfulAuthenticationActivityClass());
            //Intent i = new Intent(); 

            try
            {
                if (!(token == null || secret == null))
                {
                    mConsumer.setTokenWithSecret(token, secret);
                }
                String otoken = uri.getQueryParameter(OAuth.OAUTH_TOKEN);
                String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
                
                Assert.assertEquals(otoken, mConsumer.getToken());
                
                mProvider.retrieveAccessToken(mConsumer, verifier);
                
                token = mConsumer.getToken();
                secret = mConsumer.getTokenSecret();
                
                saveAuthInformation(token, secret);
                saveRequestInformation(null, null);
                
                i.putExtra(USER_TOKEN, token);
                i.putExtra(USER_SECRET, secret);
                
            }
            catch (Exception e)
            {
                Log.e(getPackageName(), "Unable to authenticate", e);
            }
            finally
            {
                startActivity(i);
                finish();
            }
        }
    }
    
    
    
    public void saveRequestInformation(String token, String secret)
    {
        SharedPreferences.Editor editor = mSettings.edit();
        if (token == null)
        {
            editor.remove(getRequestToken());
        }
        else
        {
            editor.putString(getRequestToken(), token);
        }
        
        if (secret == null)
        {
            editor.remove(getRequestSecret());
        }
        else
        {
            editor.putString(getRequestSecret(), secret);
        }
        
        editor.commit();
        
    }
    
    public void saveAuthInformation(String token, String secret)
    {
        SharedPreferences.Editor editor = mSettings.edit();
        if (token == null)
        {
            editor.remove(USER_TOKEN);
        }
        else
        {
            editor.putString(USER_TOKEN, token);
        }
        if (secret == null)
        {
            editor.remove(USER_SECRET);
        }
        else
        {
            editor.putString(USER_SECRET, secret);
        }
        editor.commit();
    }
    
    public OAuthConsumer getConsumer()
    {
        return mConsumer;
    }
}